
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>pymatgen.analysis.dimensionality &#8212; pymatgen 2020.7.3 documentation</title>
    <link rel="stylesheet" href="../../../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
 
<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-33990148-1']);
  _gaq.push(['_trackPageview']);
</script>

  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" accesskey="U">pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.analysis.dimensionality</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
          <div class="body" role="main">
            
  <h1>Source code for pymatgen.analysis.dimensionality</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">This module provides functions to get the dimensionality of a structure.</span>

<span class="sd">A number of different algorithms are implemented. These are based on the</span>
<span class="sd">following publications:</span>

<span class="sd">get_dimensionality_larsen:</span>
<span class="sd">  - P. M. Larsen, M. Pandey, M. Strange, K. W. Jacobsen. Definition of a</span>
<span class="sd">    scoring parameter to identify low-dimensional materials components.</span>
<span class="sd">    Phys. Rev. Materials 3, 034003 (2019).</span>

<span class="sd">get_dimensionality_cheon:</span>
<span class="sd">  - Cheon, G.; Duerloo, K.-A. N.; Sendek, A. D.; Porter, C.; Chen, Y.; Reed,</span>
<span class="sd">    E. J. Data Mining for New Two- and One-Dimensional Weakly Bonded Solids</span>
<span class="sd">    and Lattice-Commensurate Heterostructures. Nano Lett. 2017.</span>

<span class="sd">get_dimensionality_gorai:</span>
<span class="sd">  - Gorai, P., Toberer, E. &amp; Stevanovic, V. Computational Identification of</span>
<span class="sd">    Promising Thermoelectric Materials Among Known Quasi-2D Binary Compounds.</span>
<span class="sd">    J. Mater. Chem. A 2, 4136 (2016).</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">itertools</span>
<span class="kn">import</span> <span class="nn">copy</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>

<span class="kn">from</span> <span class="nn">networkx.readwrite</span> <span class="kn">import</span> <span class="n">json_graph</span>

<span class="kn">from</span> <span class="nn">pymatgen.analysis.graphs</span> <span class="kn">import</span> <span class="n">MoleculeGraph</span><span class="p">,</span> <span class="n">StructureGraph</span>
<span class="kn">from</span> <span class="nn">pymatgen.core.lattice</span> <span class="kn">import</span> <span class="n">get_integer_index</span>
<span class="kn">from</span> <span class="nn">pymatgen.core.structure</span> <span class="kn">import</span> <span class="n">Structure</span><span class="p">,</span> <span class="n">Molecule</span>
<span class="kn">from</span> <span class="nn">pymatgen.core.periodic_table</span> <span class="kn">import</span> <span class="n">Specie</span>
<span class="kn">from</span> <span class="nn">pymatgen.core.surface</span> <span class="kn">import</span> <span class="n">SlabGenerator</span>
<span class="kn">from</span> <span class="nn">pymatgen.analysis.local_env</span> <span class="kn">import</span> <span class="n">JmolNN</span>
<span class="kn">from</span> <span class="nn">pymatgen.analysis.structure_analyzer</span> <span class="kn">import</span> <span class="n">get_max_bond_lengths</span>
<span class="kn">from</span> <span class="nn">pymatgen.symmetry.analyzer</span> <span class="kn">import</span> <span class="n">SpacegroupAnalyzer</span>

<span class="n">__author__</span> <span class="o">=</span> <span class="s2">&quot;Alex Ganose, Gowoon Cheon, Prashun Gorai&quot;</span>


<div class="viewcode-block" id="get_dimensionality_larsen"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.get_dimensionality_larsen">[docs]</a><span class="k">def</span> <span class="nf">get_dimensionality_larsen</span><span class="p">(</span><span class="n">bonded_structure</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Gets the dimensionality of a bonded structure.</span>

<span class="sd">    The dimensionality of the structure is the highest dimensionality of all</span>
<span class="sd">    structure components. This method is very robust and can handle</span>
<span class="sd">    many tricky structures, regardless of structure type or improper connections</span>
<span class="sd">    due to periodic boundary conditions.</span>

<span class="sd">    Requires a StructureGraph object as input. This can be generated using one</span>
<span class="sd">    of the NearNeighbor classes. For example, using the CrystalNN class::</span>

<span class="sd">        bonded_structure = CrystalNN().get_bonded_structure(structure)</span>

<span class="sd">    Based on the modified breadth-first-search algorithm described in:</span>

<span class="sd">    P. M. Larsen, M. Pandey, M. Strange, K. W. Jacobsen. Definition of a</span>
<span class="sd">    scoring parameter to identify low-dimensional materials components.</span>
<span class="sd">    Phys. Rev. Materials 3, 034003 (2019).</span>

<span class="sd">    Args:</span>
<span class="sd">        bonded_structure (StructureGraph): A structure with bonds, represented</span>
<span class="sd">            as a pymatgen structure graph. For example, generated using the</span>
<span class="sd">            CrystalNN.get_bonded_structure() method.</span>

<span class="sd">    Returns:</span>
<span class="sd">        (int): The dimensionality of the structure.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="nb">max</span><span class="p">([</span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;dimensionality&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span>
                <span class="n">get_structure_components</span><span class="p">(</span><span class="n">bonded_structure</span><span class="p">)])</span></div>


<div class="viewcode-block" id="get_structure_components"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.get_structure_components">[docs]</a><span class="k">def</span> <span class="nf">get_structure_components</span><span class="p">(</span><span class="n">bonded_structure</span><span class="p">,</span> <span class="n">inc_orientation</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                             <span class="n">inc_site_ids</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">inc_molecule_graph</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Gets information on the components in a bonded structure.</span>

<span class="sd">    Correctly determines the dimensionality of all structures, regardless of</span>
<span class="sd">    structure type or improper connections due to periodic boundary conditions.</span>

<span class="sd">    Requires a StructureGraph object as input. This can be generated using one</span>
<span class="sd">    of the NearNeighbor classes. For example, using the CrystalNN class::</span>

<span class="sd">        bonded_structure = CrystalNN().get_bonded_structure(structure)</span>

<span class="sd">    Based on the modified breadth-first-search algorithm described in:</span>

<span class="sd">    P. M. Larsen, M. Pandey, M. Strange, K. W. Jacobsen. Definition of a</span>
<span class="sd">    scoring parameter to identify low-dimensional materials components.</span>
<span class="sd">    Phys. Rev. Materials 3, 034003 (2019).</span>

<span class="sd">    Args:</span>
<span class="sd">        bonded_structure (StructureGraph): A structure with bonds, represented</span>
<span class="sd">            as a pymatgen structure graph. For example, generated using the</span>
<span class="sd">            CrystalNN.get_bonded_structure() method.</span>
<span class="sd">        inc_orientation (bool, optional): Whether to include the orientation</span>
<span class="sd">            of the structure component. For surfaces, the miller index is given,</span>
<span class="sd">            for one-dimensional structures, the direction of the chain is given.</span>
<span class="sd">        inc_site_ids (bool, optional): Whether to include the site indices</span>
<span class="sd">            of the sites in the structure component.</span>
<span class="sd">        inc_molecule_graph (bool, optional): Whether to include MoleculeGraph</span>
<span class="sd">            objects for zero-dimensional components.</span>

<span class="sd">    Returns:</span>
<span class="sd">        (list of dict): Information on the components in a structure as a list</span>
<span class="sd">        of dictionaries with the keys:</span>

<span class="sd">        - &quot;structure_graph&quot;: A pymatgen StructureGraph object for the</span>
<span class="sd">            component.</span>
<span class="sd">        - &quot;dimensionality&quot;: The dimensionality of the structure component as an</span>
<span class="sd">            int.</span>
<span class="sd">        - &quot;orientation&quot;: If inc_orientation is `True`, the orientation of the</span>
<span class="sd">            component as a tuple. E.g. (1, 1, 1)</span>
<span class="sd">        - &quot;site_ids&quot;: If inc_site_ids is `True`, the site indices of the</span>
<span class="sd">            sites in the component as a tuple.</span>
<span class="sd">        - &quot;molecule_graph&quot;: If inc_molecule_graph is `True`, the site a</span>
<span class="sd">            MoleculeGraph object for zero-dimensional components.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">networkx</span> <span class="k">as</span> <span class="nn">nx</span>  <span class="c1"># optional dependency therefore not top level import</span>

    <span class="n">comp_graphs</span> <span class="o">=</span> <span class="p">(</span><span class="n">bonded_structure</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">subgraph</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span>
                   <span class="n">nx</span><span class="o">.</span><span class="n">weakly_connected_components</span><span class="p">(</span><span class="n">bonded_structure</span><span class="o">.</span><span class="n">graph</span><span class="p">))</span>

    <span class="n">components</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">graph</span> <span class="ow">in</span> <span class="n">comp_graphs</span><span class="p">:</span>
        <span class="n">dimensionality</span><span class="p">,</span> <span class="n">vertices</span> <span class="o">=</span> <span class="n">calculate_dimensionality_of_site</span><span class="p">(</span>
            <span class="n">bonded_structure</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">())[</span><span class="mi">0</span><span class="p">],</span> <span class="n">inc_vertices</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

        <span class="n">component</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;dimensionality&#39;</span><span class="p">:</span> <span class="n">dimensionality</span><span class="p">}</span>

        <span class="k">if</span> <span class="n">inc_orientation</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">dimensionality</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]:</span>
                <span class="n">vertices</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">vertices</span><span class="p">)</span>

                <span class="n">g</span> <span class="o">=</span> <span class="n">vertices</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="o">/</span> <span class="n">vertices</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

                <span class="c1"># run singular value decomposition</span>
                <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">vh</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">svd</span><span class="p">(</span><span class="n">vertices</span> <span class="o">-</span> <span class="n">g</span><span class="p">)</span>

                <span class="c1"># get direction (first column is best fit line,</span>
                <span class="c1"># 3rd column is unitary norm)</span>
                <span class="n">index</span> <span class="o">=</span> <span class="mi">2</span> <span class="k">if</span> <span class="n">dimensionality</span> <span class="o">==</span> <span class="mi">2</span> <span class="k">else</span> <span class="mi">0</span>
                <span class="n">orientation</span> <span class="o">=</span> <span class="n">get_integer_index</span><span class="p">(</span><span class="n">vh</span><span class="p">[</span><span class="n">index</span><span class="p">,</span> <span class="p">:])</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">orientation</span> <span class="o">=</span> <span class="kc">None</span>

            <span class="n">component</span><span class="p">[</span><span class="s1">&#39;orientation&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">orientation</span>

        <span class="k">if</span> <span class="n">inc_site_ids</span><span class="p">:</span>
            <span class="n">component</span><span class="p">[</span><span class="s1">&#39;site_ids&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">())</span>

        <span class="k">if</span> <span class="n">inc_molecule_graph</span> <span class="ow">and</span> <span class="n">dimensionality</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">component</span><span class="p">[</span><span class="s1">&#39;molecule_graph&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">zero_d_graph_to_molecule_graph</span><span class="p">(</span>
                <span class="n">bonded_structure</span><span class="p">,</span> <span class="n">graph</span><span class="p">)</span>

        <span class="n">component_structure</span> <span class="o">=</span> <span class="n">Structure</span><span class="o">.</span><span class="n">from_sites</span><span class="p">(</span>
            <span class="p">[</span><span class="n">bonded_structure</span><span class="o">.</span><span class="n">structure</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">())])</span>

        <span class="n">sorted_graph</span> <span class="o">=</span> <span class="n">nx</span><span class="o">.</span><span class="n">convert_node_labels_to_integers</span><span class="p">(</span>
            <span class="n">graph</span><span class="p">,</span> <span class="n">ordering</span><span class="o">=</span><span class="s2">&quot;sorted&quot;</span><span class="p">)</span>
        <span class="n">component_graph</span> <span class="o">=</span> <span class="n">StructureGraph</span><span class="p">(</span>
            <span class="n">component_structure</span><span class="p">,</span>
            <span class="n">graph_data</span><span class="o">=</span><span class="n">json_graph</span><span class="o">.</span><span class="n">adjacency_data</span><span class="p">(</span><span class="n">sorted_graph</span><span class="p">))</span>
        <span class="n">component</span><span class="p">[</span><span class="s1">&#39;structure_graph&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">component_graph</span>

        <span class="n">components</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">component</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">components</span></div>


<div class="viewcode-block" id="calculate_dimensionality_of_site"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.calculate_dimensionality_of_site">[docs]</a><span class="k">def</span> <span class="nf">calculate_dimensionality_of_site</span><span class="p">(</span><span class="n">bonded_structure</span><span class="p">,</span> <span class="n">site_index</span><span class="p">,</span>
                                     <span class="n">inc_vertices</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Calculates the dimensionality of the component containing the given site.</span>

<span class="sd">    Implements directly the modified breadth-first-search algorithm described in</span>
<span class="sd">    Algorithm 1 of:</span>

<span class="sd">    P. M. Larsen, M. Pandey, M. Strange, K. W. Jacobsen. Definition of a</span>
<span class="sd">    scoring parameter to identify low-dimensional materials components.</span>
<span class="sd">    Phys. Rev. Materials 3, 034003 (2019).</span>

<span class="sd">    Args:</span>
<span class="sd">        bonded_structure (StructureGraph): A structure with bonds, represented</span>
<span class="sd">            as a pymatgen structure graph. For example, generated using the</span>
<span class="sd">            CrystalNN.get_bonded_structure() method.</span>
<span class="sd">        site_index (int): The index of a site in the component of interest.</span>
<span class="sd">        inc_vertices (bool, optional): Whether to return the vertices (site</span>
<span class="sd">            images) of the component.</span>

<span class="sd">    Returns:</span>
<span class="sd">        (int or tuple): If inc_vertices is False, the dimensionality of the</span>
<span class="sd">        component will be returned as an int. If inc_vertices is true, the</span>
<span class="sd">        function will return a tuple of (dimensionality, vertices), where</span>
<span class="sd">        vertices is a list of tuples. E.g. [(0, 0, 0), (1, 1, 1)].</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">neighbours</span><span class="p">(</span><span class="n">comp_index</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">[(</span><span class="n">s</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">jimage</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span>
                <span class="ow">in</span> <span class="n">bonded_structure</span><span class="o">.</span><span class="n">get_connected_sites</span><span class="p">(</span><span class="n">comp_index</span><span class="p">)]</span>

    <span class="k">def</span> <span class="nf">rank</span><span class="p">(</span><span class="n">vertices</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">vertices</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
        <span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">vertices</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
            <span class="k">return</span> <span class="mi">0</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">vertices</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">vertices</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">matrix_rank</span><span class="p">(</span><span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="o">-</span> <span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">rank_increase</span><span class="p">(</span><span class="n">seen</span><span class="p">,</span> <span class="n">candidate</span><span class="p">):</span>

        <span class="n">rank0</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">seen</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
        <span class="n">rank1</span> <span class="o">=</span> <span class="n">rank</span><span class="p">(</span><span class="n">seen</span><span class="o">.</span><span class="n">union</span><span class="p">({</span><span class="n">candidate</span><span class="p">}))</span>
        <span class="k">return</span> <span class="n">rank1</span> <span class="o">&gt;</span> <span class="n">rank0</span>

    <span class="n">connected_sites</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">:</span> <span class="n">neighbours</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span>
                       <span class="nb">range</span><span class="p">(</span><span class="n">bonded_structure</span><span class="o">.</span><span class="n">structure</span><span class="o">.</span><span class="n">num_sites</span><span class="p">)}</span>

    <span class="n">seen_vertices</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
    <span class="n">seen_comp_vertices</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>

    <span class="n">queue</span> <span class="o">=</span> <span class="p">[(</span><span class="n">site_index</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))]</span>
    <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">queue</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">comp_i</span><span class="p">,</span> <span class="n">image_i</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">comp_i</span><span class="p">,</span> <span class="n">image_i</span><span class="p">)</span> <span class="ow">in</span> <span class="n">seen_vertices</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="n">seen_vertices</span><span class="o">.</span><span class="n">add</span><span class="p">((</span><span class="n">comp_i</span><span class="p">,</span> <span class="n">image_i</span><span class="p">))</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="n">rank_increase</span><span class="p">(</span><span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">comp_i</span><span class="p">],</span> <span class="n">image_i</span><span class="p">):</span>
            <span class="k">continue</span>

        <span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">comp_i</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">image_i</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">comp_j</span><span class="p">,</span> <span class="n">image_j</span> <span class="ow">in</span> <span class="n">connected_sites</span><span class="p">[</span><span class="n">comp_i</span><span class="p">]:</span>

            <span class="n">image_j</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">image_j</span><span class="p">,</span> <span class="n">image_i</span><span class="p">))</span>

            <span class="k">if</span> <span class="p">(</span><span class="n">comp_j</span><span class="p">,</span> <span class="n">image_j</span><span class="p">)</span> <span class="ow">in</span> <span class="n">seen_vertices</span><span class="p">:</span>
                <span class="k">continue</span>

            <span class="k">if</span> <span class="n">rank_increase</span><span class="p">(</span><span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">comp_j</span><span class="p">],</span> <span class="n">image_j</span><span class="p">):</span>
                <span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">comp_j</span><span class="p">,</span> <span class="n">image_j</span><span class="p">))</span>

    <span class="k">if</span> <span class="n">inc_vertices</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">rank</span><span class="p">(</span><span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">site_index</span><span class="p">]),</span>
                <span class="nb">list</span><span class="p">(</span><span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">site_index</span><span class="p">]))</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">rank</span><span class="p">(</span><span class="n">seen_comp_vertices</span><span class="p">[</span><span class="n">site_index</span><span class="p">])</span></div>


<div class="viewcode-block" id="zero_d_graph_to_molecule_graph"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.zero_d_graph_to_molecule_graph">[docs]</a><span class="k">def</span> <span class="nf">zero_d_graph_to_molecule_graph</span><span class="p">(</span><span class="n">bonded_structure</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Converts a zero-dimensional networkx Graph object into a MoleculeGraph.</span>

<span class="sd">    Implements a similar breadth-first search to that in</span>
<span class="sd">    calculate_dimensionality_of_site().</span>

<span class="sd">    Args:</span>
<span class="sd">        bonded_structure (StructureGraph): A structure with bonds, represented</span>
<span class="sd">            as a pymatgen structure graph. For example, generated using the</span>
<span class="sd">            CrystalNN.get_bonded_structure() method.</span>
<span class="sd">        graph (nx.Graph): A networkx `Graph` object for the component of</span>
<span class="sd">            interest.</span>

<span class="sd">    Returns:</span>
<span class="sd">        (MoleculeGraph): A MoleculeGraph object of the component.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">networkx</span> <span class="k">as</span> <span class="nn">nx</span>
    <span class="n">seen_indices</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">sites</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="n">start_index</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">queue</span> <span class="o">=</span> <span class="p">[(</span><span class="n">start_index</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
              <span class="n">bonded_structure</span><span class="o">.</span><span class="n">structure</span><span class="p">[</span><span class="n">start_index</span><span class="p">])]</span>
    <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">queue</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">comp_i</span><span class="p">,</span> <span class="n">image_i</span><span class="p">,</span> <span class="n">site_i</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">comp_i</span> <span class="ow">in</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">seen_indices</span><span class="p">]:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Graph component is not 0D&quot;</span><span class="p">)</span>

        <span class="n">seen_indices</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">comp_i</span><span class="p">,</span> <span class="n">image_i</span><span class="p">))</span>
        <span class="n">sites</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">site_i</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">site_j</span> <span class="ow">in</span> <span class="n">bonded_structure</span><span class="o">.</span><span class="n">get_connected_sites</span><span class="p">(</span>
                <span class="n">comp_i</span><span class="p">,</span> <span class="n">jimage</span><span class="o">=</span><span class="n">image_i</span><span class="p">):</span>

            <span class="k">if</span> <span class="p">((</span><span class="n">site_j</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">site_j</span><span class="o">.</span><span class="n">jimage</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">seen_indices</span> <span class="ow">and</span>
                    <span class="p">(</span><span class="n">site_j</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">site_j</span><span class="o">.</span><span class="n">jimage</span><span class="p">,</span> <span class="n">site_j</span><span class="o">.</span><span class="n">site</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">queue</span><span class="p">):</span>
                <span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">site_j</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">site_j</span><span class="o">.</span><span class="n">jimage</span><span class="p">,</span> <span class="n">site_j</span><span class="o">.</span><span class="n">site</span><span class="p">))</span>

    <span class="c1"># sort the list of indices and the graph by index to make consistent</span>
    <span class="n">indices_ordering</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">([</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">seen_indices</span><span class="p">])</span>
    <span class="n">sorted_sites</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">sites</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">object</span><span class="p">)[</span><span class="n">indices_ordering</span><span class="p">]</span>
    <span class="n">sorted_graph</span> <span class="o">=</span> <span class="n">nx</span><span class="o">.</span><span class="n">convert_node_labels_to_integers</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">ordering</span><span class="o">=</span><span class="s2">&quot;sorted&quot;</span><span class="p">)</span>
    <span class="n">mol</span> <span class="o">=</span> <span class="n">Molecule</span><span class="p">([</span><span class="n">s</span><span class="o">.</span><span class="n">specie</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">sorted_sites</span><span class="p">],</span>
                   <span class="p">[</span><span class="n">s</span><span class="o">.</span><span class="n">coords</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">sorted_sites</span><span class="p">])</span>
    <span class="n">mol_graph</span> <span class="o">=</span> <span class="n">MoleculeGraph</span><span class="o">.</span><span class="n">with_edges</span><span class="p">(</span><span class="n">mol</span><span class="p">,</span> <span class="n">nx</span><span class="o">.</span><span class="n">Graph</span><span class="p">(</span><span class="n">sorted_graph</span><span class="p">)</span><span class="o">.</span><span class="n">edges</span><span class="p">())</span>

    <span class="k">return</span> <span class="n">mol_graph</span></div>


<div class="viewcode-block" id="get_dimensionality_cheon"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.get_dimensionality_cheon">[docs]</a><span class="k">def</span> <span class="nf">get_dimensionality_cheon</span><span class="p">(</span><span class="n">structure_raw</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="mf">0.45</span><span class="p">,</span>
                             <span class="n">ldict</span><span class="o">=</span><span class="n">JmolNN</span><span class="p">()</span><span class="o">.</span><span class="n">el_radius</span><span class="p">,</span> <span class="n">standardize</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">larger_cell</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Algorithm for finding the dimensions of connected subunits in a structure.</span>
<span class="sd">    This method finds the dimensionality of the material even when the material</span>
<span class="sd">    is not layered along low-index planes, or does not have flat</span>
<span class="sd">    layers/molecular wires.</span>

<span class="sd">    Author: &quot;Gowoon Cheon&quot;</span>
<span class="sd">    Email: &quot;gcheon@stanford.edu&quot;</span>

<span class="sd">    See details at :</span>

<span class="sd">    Cheon, G.; Duerloo, K.-A. N.; Sendek, A. D.; Porter, C.; Chen, Y.; Reed,</span>
<span class="sd">    E. J. Data Mining for New Two- and One-Dimensional Weakly Bonded Solids and</span>
<span class="sd">    Lattice-Commensurate Heterostructures. Nano Lett. 2017.</span>

<span class="sd">    Args:</span>
<span class="sd">        structure_raw (Structure): A pymatgen Structure object.</span>
<span class="sd">        tolerance (float): length in angstroms used in finding bonded atoms.</span>
<span class="sd">            Two atoms are considered bonded if (radius of atom 1) + (radius of</span>
<span class="sd">            atom 2) + (tolerance) &lt; (distance between atoms 1 and 2). Default</span>
<span class="sd">            value = 0.45, the value used by JMol and Cheon et al.</span>
<span class="sd">        ldict (dict): dictionary of bond lengths used in finding bonded atoms.</span>
<span class="sd">            Values from JMol are used as default</span>
<span class="sd">        standardize: works with conventional standard structures if True. It is</span>
<span class="sd">            recommended to keep this as True.</span>
<span class="sd">        larger_cell: tests with 3x3x3 supercell instead of 2x2x2. Testing with</span>
<span class="sd">            2x2x2 supercell is faster but misclssifies rare interpenetrated 3D</span>
<span class="sd">             structures. Testing with a larger cell circumvents this problem</span>

<span class="sd">    Returns:</span>
<span class="sd">        (str): dimension of the largest cluster as a string. If there are ions</span>
<span class="sd">        or molecules it returns &#39;intercalated ion/molecule&#39;</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">standardize</span><span class="p">:</span>
        <span class="n">structure</span> <span class="o">=</span> <span class="n">SpacegroupAnalyzer</span><span class="p">(</span><span class="n">structure_raw</span><span class="p">)</span><span class="o">.</span><span class="n">get_conventional_standard_structure</span><span class="p">()</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">structure</span> <span class="o">=</span> <span class="n">structure_raw</span>
    <span class="n">structure_save</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">structure_raw</span><span class="p">)</span>
    <span class="n">connected_list1</span> <span class="o">=</span> <span class="n">find_connected_atoms</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="n">tolerance</span><span class="p">,</span> <span class="n">ldict</span><span class="o">=</span><span class="n">ldict</span><span class="p">)</span>
    <span class="n">max1</span><span class="p">,</span> <span class="n">min1</span><span class="p">,</span> <span class="n">clusters1</span> <span class="o">=</span> <span class="n">find_clusters</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">connected_list1</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">larger_cell</span><span class="p">:</span>
        <span class="n">structure</span><span class="o">.</span><span class="n">make_supercell</span><span class="p">([[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">]])</span>
        <span class="n">connected_list3</span> <span class="o">=</span> <span class="n">find_connected_atoms</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="n">tolerance</span><span class="p">,</span> <span class="n">ldict</span><span class="o">=</span><span class="n">ldict</span><span class="p">)</span>
        <span class="n">max3</span><span class="p">,</span> <span class="n">min3</span><span class="p">,</span> <span class="n">clusters3</span> <span class="o">=</span> <span class="n">find_clusters</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">connected_list3</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">min3</span> <span class="o">==</span> <span class="n">min1</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">max3</span> <span class="o">==</span> <span class="n">max1</span><span class="p">:</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;0D&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;intercalated molecule&#39;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">dim</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">max3</span><span class="p">)</span> <span class="o">/</span> <span class="n">max1</span><span class="p">)</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">dim</span> <span class="o">==</span> <span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">):</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;D&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">structure</span><span class="o">.</span><span class="n">make_supercell</span><span class="p">([[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">]])</span>
        <span class="n">connected_list2</span> <span class="o">=</span> <span class="n">find_connected_atoms</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="n">tolerance</span><span class="p">,</span> <span class="n">ldict</span><span class="o">=</span><span class="n">ldict</span><span class="p">)</span>
        <span class="n">max2</span><span class="p">,</span> <span class="n">min2</span><span class="p">,</span> <span class="n">clusters2</span> <span class="o">=</span> <span class="n">find_clusters</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">connected_list2</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">min2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;intercalated ion&#39;</span>
        <span class="k">elif</span> <span class="n">min2</span> <span class="o">==</span> <span class="n">min1</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">max2</span> <span class="o">==</span> <span class="n">max1</span><span class="p">:</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;0D&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;intercalated molecule&#39;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">dim</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">max2</span><span class="p">)</span> <span class="o">/</span> <span class="n">max1</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">dim</span> <span class="o">==</span> <span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">):</span>
                <span class="n">dim</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;D&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">structure</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">structure_save</span><span class="p">)</span>
                <span class="n">structure</span><span class="o">.</span><span class="n">make_supercell</span><span class="p">([[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">]])</span>
                <span class="n">connected_list3</span> <span class="o">=</span> <span class="n">find_connected_atoms</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="n">tolerance</span><span class="p">,</span> <span class="n">ldict</span><span class="o">=</span><span class="n">ldict</span><span class="p">)</span>
                <span class="n">max3</span><span class="p">,</span> <span class="n">min3</span><span class="p">,</span> <span class="n">clusters3</span> <span class="o">=</span> <span class="n">find_clusters</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">connected_list3</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">min3</span> <span class="o">==</span> <span class="n">min2</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">max3</span> <span class="o">==</span> <span class="n">max2</span><span class="p">:</span>
                        <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;0D&#39;</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">dim</span> <span class="o">=</span> <span class="s1">&#39;intercalated molecule&#39;</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">dim</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">max3</span><span class="p">)</span> <span class="o">/</span> <span class="n">max1</span><span class="p">)</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">dim</span> <span class="o">==</span> <span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">):</span>
                        <span class="n">dim</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">dim</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;D&#39;</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="k">return</span>
    <span class="k">return</span> <span class="n">dim</span></div>


<div class="viewcode-block" id="find_connected_atoms"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.find_connected_atoms">[docs]</a><span class="k">def</span> <span class="nf">find_connected_atoms</span><span class="p">(</span><span class="n">struct</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="mf">0.45</span><span class="p">,</span> <span class="n">ldict</span><span class="o">=</span><span class="n">JmolNN</span><span class="p">()</span><span class="o">.</span><span class="n">el_radius</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Finds bonded atoms and returns a adjacency matrix of bonded atoms.</span>

<span class="sd">    Author: &quot;Gowoon Cheon&quot;</span>
<span class="sd">    Email: &quot;gcheon@stanford.edu&quot;</span>

<span class="sd">    Args:</span>
<span class="sd">        struct (Structure): Input structure</span>
<span class="sd">        tolerance: length in angstroms used in finding bonded atoms. Two atoms</span>
<span class="sd">            are considered bonded if (radius of atom 1) + (radius of atom 2) +</span>
<span class="sd">            (tolerance) &lt; (distance between atoms 1 and 2). Default</span>
<span class="sd">            value = 0.45, the value used by JMol and Cheon et al.</span>
<span class="sd">        ldict: dictionary of bond lengths used in finding bonded atoms. Values</span>
<span class="sd">            from JMol are used as default</span>

<span class="sd">    Returns:</span>
<span class="sd">        (np.ndarray): A numpy array of shape (number of atoms, number of atoms);</span>
<span class="sd">        If any image of atom j is bonded to atom i with periodic boundary</span>
<span class="sd">        conditions, the matrix element [atom i, atom j] is 1.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">n_atoms</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">species</span><span class="p">)</span>
    <span class="n">fc</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">frac_coords</span><span class="p">)</span>
    <span class="n">fc_copy</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="n">fc</span><span class="p">[:,</span> <span class="p">:,</span> <span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">],</span> <span class="mi">27</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
    <span class="n">neighbors</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">])))</span><span class="o">.</span><span class="n">T</span>
    <span class="n">neighbors</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="n">neighbors</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:],</span> <span class="mi">1</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">fc_diff</span> <span class="o">=</span> <span class="n">fc_copy</span> <span class="o">-</span> <span class="n">neighbors</span>
    <span class="n">species</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">struct</span><span class="o">.</span><span class="n">species</span><span class="p">))</span>
    <span class="c1"># in case of charged species</span>
    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">species</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">item</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ldict</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
            <span class="n">species</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">Specie</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">item</span><span class="p">)</span><span class="o">.</span><span class="n">element</span><span class="p">)</span>
    <span class="n">latmat</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">lattice</span><span class="o">.</span><span class="n">matrix</span>
    <span class="n">connected_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">n_atoms</span><span class="p">,</span> <span class="n">n_atoms</span><span class="p">))</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_atoms</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n_atoms</span><span class="p">):</span>
            <span class="n">max_bond_length</span> <span class="o">=</span> <span class="n">ldict</span><span class="p">[</span><span class="n">species</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">+</span> <span class="n">ldict</span><span class="p">[</span><span class="n">species</span><span class="p">[</span><span class="n">j</span><span class="p">]]</span> <span class="o">+</span> <span class="n">tolerance</span>
            <span class="n">frac_diff</span> <span class="o">=</span> <span class="n">fc_diff</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">-</span> <span class="n">fc_copy</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
            <span class="n">distance_ij</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">latmat</span><span class="o">.</span><span class="n">T</span><span class="p">,</span> <span class="n">frac_diff</span><span class="p">)</span>
            <span class="c1"># print(np.linalg.norm(distance_ij,axis=0))</span>
            <span class="k">if</span> <span class="nb">sum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">distance_ij</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">max_bond_length</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">connected_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
                <span class="n">connected_matrix</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="k">return</span> <span class="n">connected_matrix</span></div>


<div class="viewcode-block" id="find_clusters"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.find_clusters">[docs]</a><span class="k">def</span> <span class="nf">find_clusters</span><span class="p">(</span><span class="n">struct</span><span class="p">,</span> <span class="n">connected_matrix</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Finds bonded clusters of atoms in the structure with periodic boundary</span>
<span class="sd">    conditions.</span>

<span class="sd">    If there are atoms that are not bonded to anything, returns [0,1,0]. (For</span>
<span class="sd">    faster computation time)</span>

<span class="sd">    Author: &quot;Gowoon Cheon&quot;</span>
<span class="sd">    Email: &quot;gcheon@stanford.edu&quot;</span>

<span class="sd">    Args:</span>
<span class="sd">        struct (Structure): Input structure</span>
<span class="sd">        connected_matrix: Must be made from the same structure with</span>
<span class="sd">            find_connected_atoms() function.</span>

<span class="sd">    Returns:</span>
<span class="sd">        max_cluster: the size of the largest cluster in the crystal structure</span>
<span class="sd">        min_cluster: the size of the smallest cluster in the crystal structure</span>
<span class="sd">        clusters: list of bonded clusters found here, clusters are formatted as</span>
<span class="sd">        sets of indices of atoms</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">n_atoms</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">species</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">n_atoms</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
    <span class="k">if</span> <span class="mi">0</span> <span class="ow">in</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">connected_matrix</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>

    <span class="n">cluster_sizes</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">clusters</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">visited</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_atoms</span><span class="p">)]</span>
    <span class="n">connected_matrix</span> <span class="o">+=</span> <span class="n">np</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">connected_matrix</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">visit</span><span class="p">(</span><span class="n">atom</span><span class="p">,</span> <span class="n">atom_cluster</span><span class="p">):</span>
        <span class="n">visited</span><span class="p">[</span><span class="n">atom</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="n">new_cluster</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">connected_matrix</span><span class="p">[</span><span class="n">atom</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">atom_cluster</span><span class="p">)</span>
        <span class="n">atom_cluster</span> <span class="o">=</span> <span class="n">new_cluster</span>
        <span class="k">for</span> <span class="n">new_atom</span> <span class="ow">in</span> <span class="n">atom_cluster</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">visited</span><span class="p">[</span><span class="n">new_atom</span><span class="p">]:</span>
                <span class="n">visited</span><span class="p">[</span><span class="n">new_atom</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="n">atom_cluster</span> <span class="o">=</span> <span class="n">visit</span><span class="p">(</span><span class="n">new_atom</span><span class="p">,</span> <span class="n">atom_cluster</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">atom_cluster</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_atoms</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">visited</span><span class="p">[</span><span class="n">i</span><span class="p">]:</span>
            <span class="n">atom_cluster</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
            <span class="n">cluster</span> <span class="o">=</span> <span class="n">visit</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">atom_cluster</span><span class="p">)</span>
            <span class="n">clusters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cluster</span><span class="p">)</span>
            <span class="n">cluster_sizes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">cluster</span><span class="p">))</span>

    <span class="n">max_cluster</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">cluster_sizes</span><span class="p">)</span>
    <span class="n">min_cluster</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">cluster_sizes</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">max_cluster</span><span class="p">,</span> <span class="n">min_cluster</span><span class="p">,</span> <span class="n">clusters</span><span class="p">]</span></div>


<div class="viewcode-block" id="get_dimensionality_gorai"><a class="viewcode-back" href="../../../pymatgen.analysis.dimensionality.html#pymatgen.analysis.dimensionality.get_dimensionality_gorai">[docs]</a><span class="k">def</span> <span class="nf">get_dimensionality_gorai</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">max_hkl</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">el_radius_updates</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">min_slab_size</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">min_vacuum_size</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
                             <span class="n">standardize</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bonds</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    This method returns whether a structure is 3D, 2D (layered), or 1D (linear</span>
<span class="sd">    chains or molecules) according to the algorithm published in Gorai, P.,</span>
<span class="sd">    Toberer, E. &amp; Stevanovic, V. Computational Identification of Promising</span>
<span class="sd">    Thermoelectric Materials Among Known Quasi-2D Binary Compounds. J. Mater.</span>
<span class="sd">    Chem. A 2, 4136 (2016).</span>

<span class="sd">    Note that a 1D structure detection might indicate problems in the bonding</span>
<span class="sd">    algorithm, particularly for ionic crystals (e.g., NaCl)</span>

<span class="sd">    Users can change the behavior of bonds detection by passing either</span>
<span class="sd">    el_radius_updates to update atomic radii for auto-detection of max bond</span>
<span class="sd">    distances, or bonds to explicitly specify max bond distances for atom pairs.</span>
<span class="sd">    Note that if you pass both, el_radius_updates are ignored.</span>

<span class="sd">    Args:</span>
<span class="sd">        structure: (Structure) structure to analyze dimensionality for</span>
<span class="sd">        max_hkl: (int) max index of planes to look for layers</span>
<span class="sd">        el_radius_updates: (dict) symbol-&gt;float to update atomic radii</span>
<span class="sd">        min_slab_size: (float) internal surface construction parameter</span>
<span class="sd">        min_vacuum_size: (float) internal surface construction parameter</span>
<span class="sd">        standardize (bool): whether to standardize the structure before</span>
<span class="sd">            analysis. Set to False only if you already have the structure in a</span>
<span class="sd">            convention where layers / chains will be along low &lt;hkl&gt; indexes.</span>
<span class="sd">        bonds ({(specie1, specie2): max_bond_dist}: bonds are</span>
<span class="sd">                specified as a dict of tuples: float of specie1, specie2</span>
<span class="sd">                and the max bonding distance. For example, PO4 groups may be</span>
<span class="sd">                defined as {(&quot;P&quot;, &quot;O&quot;): 3}.</span>

<span class="sd">    Returns: (int) the dimensionality of the structure - 1 (molecules/chains),</span>
<span class="sd">        2 (layered), or 3 (3D)</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">standardize</span><span class="p">:</span>
        <span class="n">structure</span> <span class="o">=</span> <span class="n">SpacegroupAnalyzer</span><span class="p">(</span><span class="n">structure</span><span class="p">)</span><span class="o">.</span> \
            <span class="n">get_conventional_standard_structure</span><span class="p">()</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">bonds</span><span class="p">:</span>
        <span class="n">bonds</span> <span class="o">=</span> <span class="n">get_max_bond_lengths</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">el_radius_updates</span><span class="p">)</span>

    <span class="n">num_surfaces</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_hkl</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_hkl</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_hkl</span><span class="p">):</span>
                <span class="k">if</span> <span class="nb">max</span><span class="p">([</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">l</span><span class="p">])</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">num_surfaces</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
                    <span class="n">sg</span> <span class="o">=</span> <span class="n">SlabGenerator</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">l</span><span class="p">),</span>
                                       <span class="n">min_slab_size</span><span class="o">=</span><span class="n">min_slab_size</span><span class="p">,</span>
                                       <span class="n">min_vacuum_size</span><span class="o">=</span><span class="n">min_vacuum_size</span><span class="p">)</span>
                    <span class="n">slabs</span> <span class="o">=</span> <span class="n">sg</span><span class="o">.</span><span class="n">get_slabs</span><span class="p">(</span><span class="n">bonds</span><span class="p">)</span>
                    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">slabs</span><span class="p">:</span>
                        <span class="n">num_surfaces</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">return</span> <span class="mi">3</span> <span class="o">-</span> <span class="nb">min</span><span class="p">(</span><span class="n">num_surfaces</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span></div>
</pre></div>

            <div class="clearer"></div>
          </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" >pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.analysis.dimensionality</a></li> 
      </ul>
    </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2011, Pymatgen Development Team.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.2.
    </div>
<div class="footer">This page uses <a href="http://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script type="text/javascript">
  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ?
              'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
</div>

  </body>
</html>